package com.jiyun.jiyunmall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jiyun.jiyunmall.common.service.impl.CrudServiceImpl;
import com.jiyun.jiyunmall.product.dao.CategoryDao;
import com.jiyun.jiyunmall.product.dto.CategoryDTO;
import com.jiyun.jiyunmall.product.entity.CategoryEntity;
import com.jiyun.jiyunmall.product.service.CategoryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 商品三级分类
 *
 * @author boge 71164376@qq.com
 * @since 1.0.0 2022-07-12
 */
@Service
public class CategoryServiceImpl extends CrudServiceImpl<CategoryDao, CategoryEntity, CategoryDTO> implements CategoryService {

    @Autowired
    CategoryDao categoryDao;

    @Override
    public QueryWrapper<CategoryEntity> getWrapper(Map<String, Object> params){
        String id = (String)params.get("id");

        QueryWrapper<CategoryEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id);

        return wrapper;
    }

    /**
     * 查询所有菜单项  并以三级分类的形式进行组装
     * 1、查询所有菜单项
     * 2、并根据pid与id的映射关系，组织树形菜单
     * @return
     */
    @Override
    public CategoryDTO tree() {
        //1 查询所有菜单列表
        List<CategoryEntity> categoryEntities = categoryDao.selectList(null);
        //将所有entity拷贝一份，变成dto，存到一个新的list集合中
        ArrayList<CategoryDTO> categoryDTOS = new ArrayList<>();
        for (CategoryEntity categoryEntity : categoryEntities) {
            CategoryDTO categoryDTO = new CategoryDTO();
            BeanUtils.copyProperties(categoryEntity,categoryDTO);
            categoryDTOS.add(categoryDTO);
        }
        //2 以三级分类的形式 组装数据，只有三级
        //先找第一级、再找第二级、再找第三级， 使用递归的方式进行实现
        //id=0为顶级菜单 从顶级菜单开始
        CategoryDTO root = new CategoryDTO();
        root.setCatId(0L);

        //递归查找  将所有数据和根菜单传进去，在里面进行递归查找 拼接三级菜单
        //使用的引用传递
        concatMenuList(categoryDTOS,root);




        //拼接完三级菜单以后 将最终的对象返回就好
        return root;
    }

    private void concatMenuList(List<CategoryDTO> categoryEntities, CategoryDTO root) {
        //1查找当前root 父节点的子节点们，条件是子节点的pid=父节点的catId
        List<CategoryDTO> collect = categoryEntities.stream().filter((category) -> {
                    //过滤规则
                    if (category.getParentCid().equals(root.getCatId())) {
                        return true;
                    }
                    return false;
                }
        ).sorted(( category1,  category2) -> {
            //一定要确定sort一定是有值的  不然会报空指针  可以在建表的时候设置个not null
                //参数1-参数2：返回正数，参数1大于参数2，参数1排右边，效果=升序
                //参数2-参数1：返回正数，参数2大于参数1，参数2排右边，效果=降序
            Integer sort1 = category1.getSort()==null?0:category1.getSort();
            Integer sort2 = category2.getSort()==null?0:category2.getSort();
            return sort1-sort2;
            }
        )
         .map(categoryDTO -> {
            //2递归遍历每一个子节点  去给子节点找每一个子节点的子节点
            concatMenuList(categoryEntities,categoryDTO);
            return categoryDTO;
        })
                //收集 处理完的数据
                .collect(Collectors.toList());
        //3向父菜单保存子菜单
        if(collect.size()>0) {
            root.setChildrens(collect);
        }else{
            root.setChildrens(null);
        }
    }
}